/**
 * Copyright (C) 2016 Hyphenate Inc. All rights reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.srwl.mytx.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.alibaba.fastjson.JSONObject;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.animation.Animation;
import com.amap.api.maps.model.animation.TranslateAnimation;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.srwl.mytx.R;
import com.srwl.mytx.adapter.AddressSearchResultAdapter;
import com.srwl.mytx.widget.AddressSearchResultView;
import com.srwl.mytx.widget.AddressSearchView;

import java.util.ArrayList;

/**
 * 选取定位的页面
 */
public class PickLocationMapActivity extends BaseActivity implements AMapLocationListener, AMap.OnMyLocationChangeListener, AMap.OnCameraChangeListener, GeocodeSearch.OnGeocodeSearchListener, AddressSearchResultAdapter.OnItemClickListener {

    private static final String TAG = "MapActivity";
    public static final String EXTRA_DATA_LATITUDE = "latitude";
    public static final String EXTRA_DATA_LONGITUDE = "longitude";
    private MapView mMapView = null;
    private AMapLocationClient mlocationClient;
    // private MyTitleBar titleBar;
    private ProgressDialog progressDialog;
    private AMap aMap;
    private AMapLocation lastLocation;
    private Marker screenMarker;
    private double latitude;
    private double longitude;
    private LatLng latLng;
    private GeocodeSearch geocodeSearch;
    private TextView tv_address;
    private String simpleAddress;
    private MyLocationStyle myLocationStyle;
    private ImageButton btn_location;
    private AddressSearchView searchView;
    private ImageView ivScaleAdd;
    private ImageView ivScaleReduce;
    private ConstraintLayout clContainer;
    private AddressSearchResultView addressSearchResultView;
    private ArrayList<PoiItem> poiItemArrayList = new ArrayList<>();
    private BottomSheetBehavior<View> bottomSheetBehavior;
    private int tryLocationCount;
    private Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //initialize SDK with context, should call this before setContentView

        setContentView(R.layout.activity_pick_location);
        mMapView = findViewById(R.id.a_map_view);
        tv_address = findViewById(R.id.tv_address);
        btn_location = findViewById(R.id.btn_map_status);
        addressSearchResultView = findViewById(R.id.address_result);
        addressSearchResultView.init(poiItemArrayList);
        addressSearchResultView.setListener(this);
        initBottomSheetBehavior();
        btn_location.setVisibility(View.VISIBLE);
        mMapView.onCreate(savedInstanceState);
        btn_location.setOnClickListener(v -> location(MyLocationStyle.LOCATION_TYPE_LOCATE));
        searchView = findViewById(R.id.search_view);

        clContainer = findViewById(R.id.cl_container);
        ivScaleAdd = findViewById(R.id.iv_scale_add);
        ivScaleReduce = findViewById(R.id.iv_scale_reduce);
        ivScaleAdd.setOnClickListener(v -> aMap.animateCamera(CameraUpdateFactory.zoomIn()));
        ivScaleReduce.setOnClickListener(v -> aMap.animateCamera(CameraUpdateFactory.zoomOut()));
        initTitleBar();
        Intent intent = getIntent();
        latitude = intent.getDoubleExtra(EXTRA_DATA_LATITUDE, 0);
        longitude = intent.getDoubleExtra(EXTRA_DATA_LONGITUDE, 0);
        aMap = mMapView.getMap();
        mMapView.getMap();
        aMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
            @Override
            public void onMapLoaded() {


                addMarkerInScreenCenter();

            }
        });
        initMapView();

        initLocation();

        //如果是选择地址，没有传经纬度进来，那就定位
        if (latitude != 0 && longitude != 0) {
            LatLng latLng = new LatLng(latitude, longitude);
            showMap(latLng);
        }
    }

    void initTitleBar() {
//        titleBar = findViewById(R.id.title_bar);
//        titleBar.setRightTitle("确定");
//        titleBar.setRightLayoutClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                sendLocation();
//            }
//        });
//        titleBar.setLeftLayoutClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                finish();
//            }
//        });
        searchView.setListener(new AddressSearchView.InteractionListener() {
            @Override
            public void onSearch(String content) {
                if (!TextUtils.isEmpty(content)) {
                    hideSoftKeyboard();
                    search(content);
                }
            }

            @Override
            public void onConfirm() {
                sendLocation();
            }
        });

    }

    private void search(String keyWord) {
        PoiSearch.Query query = new PoiSearch.Query(keyWord, "", "");
        query.setPageSize(10);
        PoiSearch poiSearch = new PoiSearch(this, query);
        poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
            @Override
            public void onPoiSearched(PoiResult poiResult, int i) {
                Log.i(TAG, "onPoiSearched: " + JSONObject.toJSONString(poiResult));
                ArrayList<PoiItem> pois = poiResult.getPois();
//                TopicDialog dialog = new TopicDialog(PickLocationMapActivity.this, pois);
//                dialog.setCanceledOnTouchOutside(false);
//                dialog.setCallBack(new BottomSheetDialog.CallBack() {
//                    @Override
//                    public void onScrolled(float scrollY) {
//                        clZoomContainer.setTranslationY(-scrollY);
//                    }
//                });
//                dialog.show();
                if (pois != null && pois.size() != 0) {
                    poiItemArrayList.clear();
                    poiItemArrayList.addAll(pois);
                    addressSearchResultView.notifyDataSetChange();
                    bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                } else {
                    //显示搜索建议
                    Toast.makeText(PickLocationMapActivity.this, "没有搜到相关内容", Toast.LENGTH_LONG).show();
                }

            }

            @Override
            public void onPoiItemSearched(PoiItem poiItem, int i) {
                Log.i(TAG, "onPoiSearched: " + JSONObject.toJSONString(poiItem));
            }
        });

        poiSearch.searchPOIAsyn();
    }

    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (amapLocation != null) {
            if (amapLocation.getErrorCode() == 0) {
                if (progressDialog != null) {
                    progressDialog.dismiss();
                }
                mlocationClient.stopLocation();
                lastLocation = amapLocation;
                //定位成功回调信息，设置相关消息
                amapLocation.getLocationType();//获取当前定位结果来源，如网络定位结果，详见定位类型表
                amapLocation.getLatitude();//获取纬度
                amapLocation.getLongitude();//获取经度
                amapLocation.getAccuracy();//获取精度信息
                LatLng latLng = new LatLng(amapLocation.getLatitude(), amapLocation.getLatitude());
                CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                        latLng, 18, 30, 30));
                aMap.moveCamera(cameraUpdate);

                aMap.addMarker(new MarkerOptions().position(latLng)
                        .icon(BitmapDescriptorFactory
                                .defaultMarker(BitmapDescriptorFactory.HUE_RED)));


            } else {
                //显示错误信息ErrCode是错误码，errInfo是错误信息，详见错误码表。
                Log.e("AmapError", "location Error, ErrCode:"
                        + amapLocation.getErrorCode() + ", errInfo:"
                        + amapLocation.getErrorInfo());
            }
        }
    }

    private void showMap(LatLng latLng) {

        getAddressByLatlng(latLng);
        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                latLng, 18, 30, 30));
        aMap.moveCamera(cameraUpdate);
//        mBaiduMap.addMarker(new MarkerOptions().position(latLng)
//                .icon(BitmapDescriptorFactory
//                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
    }

    private void showMapWithLocationClient() {
        String str1 = getResources().getString(R.string.Making_sure_your_location);
        progressDialog = new ProgressDialog(this);
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage(str1);

        progressDialog.setOnCancelListener(new OnCancelListener() {

            public void onCancel(DialogInterface arg0) {
                if (progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
                Log.d("map", "cancel retrieve location");
                finish();
            }
        });

        progressDialog.show();

        mlocationClient = new AMapLocationClient(this);
        mlocationClient.setLocationListener(this);
        //声明mLocationOption对象
        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
        //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setInterval(2000);
//设置定位参数
        mlocationClient.setLocationOption(mLocationOption);
        mlocationClient.startLocation();
    }


    private void initLocation() {


        aMap = mMapView.getMap();
        UiSettings mUiSettings = aMap.getUiSettings();

        //设置不显示指南针
        mUiSettings.setCompassEnabled(false);
        mUiSettings.setZoomControlsEnabled(false);
        //显示定位按键
        // mUiSettings.setMyLocationButtonEnabled(true);
        myLocationStyle = new MyLocationStyle();
        if (latitude != 0 && longitude != 0) {
            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);// LOCATION_TYPE_LOCATE:定位一次 ，地图不移动到定位点
        } else {

            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);// LOCATION_TYPE_LOCATE:定位一次 ，地图移动到定位地点 LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER:连续定位，图标转动，
        }

        myLocationStyle.showMyLocation(true);
        myLocationStyle.anchor(0.5f, 0.5f);
        // myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.compass));
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
        myLocationStyle.strokeWidth(1f);
        myLocationStyle.interval(5000);//连续定位模式下的定位间隔时间
        aMap.setMyLocationStyle(myLocationStyle);
        // 是否可触发定位并显示定位层
        aMap.setMyLocationEnabled(true);

        //设置缩放级别
        aMap.animateCamera(CameraUpdateFactory.zoomTo(17));
        //设置地图倾斜度

        aMap.animateCamera(CameraUpdateFactory.changeTilt(30));

        aMap.setOnMyLocationChangeListener(this);
        aMap.setOnCameraChangeListener(this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mMapView.onSaveInstanceState(outState);
    }

    @Override
    protected void onPause() {
        mMapView.onPause();

        super.onPause();

    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        if (mlocationClient != null)
            mlocationClient.onDestroy();
        mMapView.onDestroy();

        super.onDestroy();
    }

    private void initMapView() {
        mMapView.setLongClickable(true);
        geocodeSearch = new GeocodeSearch(this);
        geocodeSearch.setOnGeocodeSearchListener(this);

    }


    /**
     * 在屏幕中心添加一个Marker
     */
    private void addMarkerInScreenCenter() {
        LatLng latLng;
        if (latitude != 0 && longitude != 0) {
            latLng = new LatLng(latitude, longitude);
        } else {
            latLng = aMap.getCameraPosition().target;
        }

        Point screenPosition = aMap.getProjection().toScreenLocation(latLng);
        screenMarker = aMap.addMarker(new MarkerOptions()
                .anchor(0.5f, 0.5f)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.purple_pin)));
        screenMarker.setPositionByPixels(screenPosition.x, screenPosition.y);


    }

    /**
     * 屏幕中心marker 跳动
     */
    public void startJumpAnimation() {

        if (screenMarker != null) {
            //根据屏幕距离计算需要移动的目标点
            final LatLng latLng = screenMarker.getPosition();
            Point point = aMap.getProjection().toScreenLocation(latLng);
            point.y -= dip2px(this, 50);
            LatLng target = aMap.getProjection()
                    .fromScreenLocation(point);
            //使用TranslateAnimation,填写一个需要移动的目标点
            Animation animation = new TranslateAnimation(target);
            animation.setInterpolator(new Interpolator() {
                @Override
                public float getInterpolation(float input) {
                    // 模拟重加速度的interpolator
                    if (input <= 0.5) {
                        return (float) (0.5f - 2 * (0.5 - input) * (0.5 - input));
                    } else {
                        return (float) (0.5f - Math.sqrt((input - 0.5f) * (1.5f - input)));
                    }
                }
            });
            //整个移动所需要的时间
            animation.setDuration(600);
            //设置动画
            screenMarker.setAnimation(animation);
            //开始动画
            screenMarker.startAnimation();

        } else {
            Log.e("amap", "screenMarker is null");
        }
    }

    public void back(View v) {
        finish();
    }

    //dip和px转换
    private static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public void sendLocation() {
        Intent intent = this.getIntent();
        //intent.putExtra("location", latLng);
        if (latLng != null) {
            intent.putExtra("latitude", latLng.latitude);
            intent.putExtra("longitude", latLng.longitude);
        }
        intent.putExtra("address", simpleAddress);
        this.setResult(RESULT_OK, intent);
        finish();
        overridePendingTransition(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
    }

    private void getAddressByLatlng(LatLng latLng) { //逆地理编码查询条件：逆地理编码查询的地理坐标点、查询范围、坐标类型。
        LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 500f, GeocodeSearch.AMAP); //异步查询
        geocodeSearch.getFromLocationAsyn(query);
    }

    @Override
    public void onMyLocationChange(Location location) {

        if (location.getLatitude() == 0.0 && location.getLongitude() == 0.0) {
            tryLocationCount++;
            Log.e(TAG, "onMyLocationChange: 定位失败，重启定位,tryLocationCount:" + tryLocationCount);
            if (tryLocationCount < 5) {
                handler.postDelayed(
                        new Runnable() {
                            @Override
                            public void run() {
                                if (latitude != 0 && longitude != 0) {
                                    location(MyLocationStyle.LOCATION_TYPE_SHOW);
                                } else {
                                    location(MyLocationStyle.LOCATION_TYPE_LOCATE);
                                }
                            }
                        }
                        , tryLocationCount * 1000);
            }
        } else {
            Log.d(TAG, "onMyLocationChange: 定位成功了");

        }
        // addMarkerInScreenCenter();

    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        Log.d(TAG, "onCameraChangeFinish: 地图移动了");
        LatLng target = cameraPosition.target;
        if (target == null || (target.equals(latLng))) {
            return;
        }
        latLng = target;
//        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
//                latLng, 18, 30, 30));
//        mBaiduMap.moveCamera(cameraUpdate);
//
//        mBaiduMap.addMarker(new MarkerOptions().position(latLng)
//                .icon(BitmapDescriptorFactory
//                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));

        getAddressByLatlng(latLng);
        startJumpAnimation();

    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
        RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
        simpleAddress = regeocodeAddress.getFormatAddress();
        tv_address.setText(simpleAddress);
    }

    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

    }

    //定位
    public void location(int locationType) {
        aMap.animateCamera(CameraUpdateFactory.changeBearing(0));
        aMap.animateCamera(CameraUpdateFactory.changeTilt(50));
        myLocationStyle.myLocationType(locationType);
        aMap.setMyLocationStyle(myLocationStyle);//
    }

    private void initBottomSheetBehavior() {
        bottomSheetBehavior = BottomSheetBehavior.from(addressSearchResultView);
        bottomSheetBehavior.setHideable(true);
        //设置默认先隐藏
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);

        bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View view, int newState) {
                Log.d(TAG, "onStateChanged: " + newState);
//                if (newState == BottomSheetBehavior.STATE_SETTLING) {//&& slideOffset < 0
//                    if ((lastStatus == BottomSheetBehavior.STATE_COLLAPSED && slideOffset <= 0) || (lastStatus == BottomSheetBehavior.STATE_EXPANDED && bottomSheetBehavior.getSkipCollapsed())) {
//                    }
//                }
//                if (newState == BottomSheetBehavior.STATE_COLLAPSED || (newState == BottomSheetBehavior.STATE_EXPANDED)) {
//                    lastStatus = newState;
//                }


//                if (newState == BottomSheetBehavior.STATE_HIDDEN) {
//                    commentBottomBar.hideCommentEditView();
//                    //bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
//                }
            }

            @Override
            public void onSlide(@NonNull View view, float slideOffset) {
                Log.d(TAG, "onSlide: " + slideOffset);
                float scrollY = ((1 + slideOffset) * view.getHeight());
                if (!Float.isNaN(scrollY)) {
                    clContainer.setTranslationY(-scrollY);
                    mMapView.setTranslationY(-scrollY / 2);

//                    ViewGroup.LayoutParams layoutParams = clContainer.getLayoutParams(); 改变高度的方式会卡顿，clContainer高度变化刷新的速度跟不上 addressSearchResultView 移动的速度
//                    if (height == 0) {//获取原始高度
//                        height = clContainer.getHeight();
//                    }
//                    //int height = layoutParams.height;
//                    layoutParams.height = (int) (height - scrollY);
//                    clContainer.setLayoutParams(layoutParams);
                }
            }
        });
    }

    @Override
    public void onClick(PoiItem poiItem) {
        searchView.onSearchResultSelected();
        LatLonPoint latLonPoint = poiItem.getLatLonPoint();
        if (latLonPoint != null) {

            latLng = new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
            showMap(latLng);
        }

    }
}
